import { Database, Statement } from 'better-sqlite3';
import { SqlExecuteResult, SqlExecutor } from './types';

/**
 * Better-SQLite3执行器
 * 封装对better-sqlite3的调用
 */
export class BetterSqliteExecutor implements SqlExecutor {
  /** 内部数据库连接实例 */
  private db: Database;
  
  /** 预处理语句缓存 */
  private statementCache: Map<string, Statement> = new Map();
  
  /** 是否开启调试模式 */
  private debug: boolean = false;
  
  /** 当前事务 */
  private currentTransaction?: Transaction;

  /**
   * 构造函数
   * @param db better-sqlite3数据库实例
   * @param options 选项
   */
  constructor(db: Database, options?: { debug?: boolean }) {
    this.db = db;
    this.debug = options?.debug || false;
  }

  /**
   * 执行SQL查询语句并返回多行结果
   * @param sql SQL语句
   * @param params 参数对象
   */
  public query<T = any>(sql: string, params?: Record<string, any>): T[] {
    this.logSql(sql, params);
    
    try {
      const stmt = this.prepareStatement(sql);
      return stmt.all(params || {}) as T[];
    } catch (err) {
      this.handleError(err, sql, params);
      throw err;
    }
  }

  /**
   * 执行SQL查询语句并返回单行结果
   * @param sql SQL语句
   * @param params 参数对象
   */
  public queryOne<T = any>(sql: string, params?: Record<string, any>): T | undefined {
    this.logSql(sql, params);
    
    try {
      const stmt = this.prepareStatement(sql);
      return stmt.get(params || {}) as T | undefined;
    } catch (err) {
      this.handleError(err, sql, params);
      throw err;
    }
  }

  /**
   * 执行SQL语句（插入、更新、删除等）
   * @param sql SQL语句
   * @param params 参数对象
   */
  public execute(sql: string, params?: Record<string, any>): SqlExecuteResult {
    this.logSql(sql, params);
    
    try {
      const stmt = this.prepareStatement(sql);
      const result = stmt.run(params || {});
      
      return {
        changes: result.changes,
        lastInsertRowid: result.lastInsertRowid
      };
    } catch (err) {
      this.handleError(err, sql, params);
      throw err;
    }
  }

  /**
   * 执行事务
   * @param callback 事务回调函数
   */
  public transaction<T>(callback: (executor: SqlExecutor) => T): T {
    // 如果已经在事务中，使用现有事务
    if (this.currentTransaction) {
      return callback(this);
    }
    
    // 创建新事务
    try {
      // 开始事务
      this.db.prepare('BEGIN TRANSACTION').run();
      
      // 创建事务对象
      this.currentTransaction = new Transaction(this);
      
      // 执行回调
      const result = callback(this);
      
      // 提交事务
      this.db.prepare('COMMIT').run();
      
      // 清除当前事务
      this.currentTransaction = undefined;
      
      return result;
    } catch (err) {
      // 回滚事务
      if (this.db.inTransaction) {
        this.db.prepare('ROLLBACK').run();
      }
      
      // 清除当前事务
      this.currentTransaction = undefined;
      
      throw err;
    }
  }

  /**
   * 获取预处理语句
   * @param sql SQL语句
   */
  private prepareStatement(sql: string): Statement {
    // 优先从缓存获取
    let stmt = this.statementCache.get(sql);
    
    // 如果不存在，创建并缓存
    if (!stmt) {
      stmt = this.db.prepare(sql);
      this.statementCache.set(sql, stmt);
    }
    
    return stmt;
  }

  /**
   * 记录SQL日志
   * @param sql SQL语句
   * @param params 参数对象
   */
  private logSql(sql: string, params?: Record<string, any>): void {
    if (this.debug) {
      console.log(`SQL: ${sql}`);
      if (params) {
        console.log('Params:', params);
      }
    }
  }

  /**
   * 处理SQL错误
   * @param err 错误对象
   * @param sql SQL语句
   * @param params 参数对象
   */
  private handleError(err: any, sql: string, params?: Record<string, any>): void {
    console.error('SQL Error:', err.message);
    console.error('SQL:', sql);
    if (params) {
      console.error('Params:', params);
    }
  }
}

/**
 * 事务类
 * 用于支持嵌套事务管理
 */
class Transaction {
  constructor(private executor: BetterSqliteExecutor) {}
  
  /**
   * 提交事务
   */
  public commit(): void {
    // 实际提交由外层事务控制
  }
  
  /**
   * 回滚事务
   */
  public rollback(): void {
    throw new Error('Transaction rolled back');
  }
} 